#include <iostream>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

using namespace std;

//当我们程序运行起来之后,变成了进程,默认情况下
//OS会帮我们打开三个标准输入输出
//系统层面的文件描述符:
//0:标准输入->键盘
//1:标准输出->显示器
//2:标准错误->显示器
//语言层面的FILE*:
//stdin:标准输入:键盘
//stdout:标准输出:显示器
//stderr:标准错误:显示器

//如果一个文件没有被打开,那么这个文件是保存在磁盘里面的
//如果我创建一个空文件,那么这个文化吗会不会占用磁盘空间?
//必须要占用空间,因为文件有属性,属性也是数据
//磁盘文件 = 文件内容 + 文件属性
//我们之前学的所有的文件操作,无非就是对文件的内容操作
//对文件的属性进行修改(比如改文件的名字和文件的权限)

//我们进程运行了起来,OS系统一定打开了多个文件
//所以操作系统需要对这些打开的文件进行管理
//谈到管理,那么就需要先描述,再组织
//系统内核会创建对应的
//struct file
//{
//    //文件的相关属性信息
//}
//来对文件进行描述
//这些struct file文件在内核中以双链表的形式链接在一起

//那么这么多的struct file,我怎么知道,我这个进程所创建的进程是哪一个?
//那么我们运行的一个进程,他有对应的pcb,pcb里面有一个
//struct file_struct* files的指针
//这个指针指向的是一个struct file_struct
//这个结构体里面有一个数组struct file* fd_array[],这个数组里面存储着
//struct file*,这里面每一哥指针指向的都是内核中的struct file
//那么这个数组的下标就是文件描述符
//可以根据文件描述符,然后拿到这个数组对应file* ,然后找到对应的文件
//同时可以得出一个结论:fd的本质是内核中进程和文件关联的数组的下标

//如何简单理解linux下一切皆文件?
//struct_file里面有一个成员类型很有趣，
//叫struct file_operations* f_op
//这个被指向的结构体,里面有着各种的函数指针
//我们从硬件的角度来进行理解
//在系统层面,我们要对这些硬件进行操作
//我们就需要创建硬件对应的文件,这些文件我们需要进行维护
//所以我们每个硬件有对应的struct_file
//这个结构体里面有这个硬件对应的读方法和写方法(驱动层面实现的)
//其本质就是函数指针
//在struct_file上层看来,我需要读,就调用你的读方法
//我需要写,就调用你的写方法
//实现了以文件的角度来管理所有的硬件

//总结一下：为什么linux一切都可以是文件，并不是说实体是文件，而是以文件的方式去做管理，以文件的角度去看待硬件和软件

int main()
{
    //既然文件描述符0,1,2也是文件,那么我们可以试试
    
    //读取键盘
    char buffer1[64];
    ssize_t s1 = read(0, buffer1, sizeof(buffer1));
    buffer1[s1 - 1] = '\0';
    cout << buffer1 << endl;

    //向显示屏标准打印
    const char* msg1 = "开哥牛逼!!!\n";
    ssize_t s2 = write(1, msg1, strlen(msg1));
    ssize_t s3 = write(1, msg1, strlen(msg1));
    ssize_t s4 = write(1, msg1, strlen(msg1));
    ssize_t s5 = write(1, msg1, strlen(msg1));

    //向显示屏错误打印
    const char* msg2 = "小磊牛逼!!!\n";
    ssize_t s6 = write(2, msg2, strlen(msg2));
    ssize_t s7 = write(2, msg2, strlen(msg2));
    ssize_t s8 = write(2, msg2, strlen(msg2));
    ssize_t s9 = write(2, msg2, strlen(msg2));

    return 0;
}
